package com.cskaoyan.service.admin;

import com.cskaoyan.bean.*;

import com.cskaoyan.bean.MarketCoupon;
import com.cskaoyan.bean.MarketCouponExample;
import com.cskaoyan.bean.MarketCouponUser;

import com.cskaoyan.bean.common.BasePageInfo;
import com.cskaoyan.bean.common.BaseRespVo;
import com.cskaoyan.bean.common.CommonData;
import com.cskaoyan.bean.common.CouponUserConstant;
import com.cskaoyan.bean.vo.wx.coupon.WxUserCouponVo;
import com.cskaoyan.mapper.MarketCartMapper;
import com.cskaoyan.mapper.MarketCouponMapper;
import com.cskaoyan.mapper.MarketCouponUserMapper;
import com.cskaoyan.utils.CdkCreateUtils;
import com.cskaoyan.utils.StringUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author by yxy_8175@163.com
 * @Description TODO
 * @Date 2022-11-19 20:30
 */

@Service
public class CouponServiceImpl implements CouponService {

    @Autowired
    MarketCouponMapper couponMapper;
    @Autowired
    MarketCouponUserMapper couponUserMapper;
    @Autowired
    MarketCartMapper cartMapper;

    /**
     * 分页查询优惠券数据
     *
     * @param info
     * @return
     */
    @Override
    public CommonData<MarketCoupon> selectByPage(BasePageInfo info, String name, Integer type, Integer status) {

        PageHelper.startPage(info.getPage(), info.getLimit());

        MarketCouponExample example = new MarketCouponExample();
        MarketCouponExample.Criteria criteria = example.createCriteria();

        if (name != null) {
            criteria.andNameLike("%" + name + "%");
        }
        if (type != null) {
            String typeStr = Integer.toString(type);
            criteria.andTypeEqualTo(Short.parseShort(typeStr));
        }
        if (status != null) {
            String statusStr = Integer.toString(status);
            criteria.andStatusEqualTo(Short.parseShort(statusStr));
        }
        criteria.andDeletedEqualTo(false);

        // List<MarketCoupon> list =  couponMapper.selectAll();
        List<MarketCoupon> list = couponMapper.selectByExample(example);

        PageInfo<MarketCoupon> marketCouponPageInfo = new PageInfo<>(list);

        return CommonData.data(marketCouponPageInfo);
    }

    /*
     * @Description 查询优惠券详细信息
     * @param id 优惠券表主键id
     * @return
     * @date 2022-11-22 10:27
     * @auther yxy_8175@163.com
     */
    @Override
    public MarketCoupon queryCouponInfoById(Integer id) {
        return couponMapper.selectByPrimaryKey(id);
    }

    @Transactional
    @Override
    public MarketCoupon createCoupon(MarketCoupon marketCoupon) {
        // 新人券限制为1
        Short couponLimit = 1;

        // 添加 增加时间和更新时间
        marketCoupon.setAddTime(new Date());
        marketCoupon.setUpdateTime(new Date());

        // 需要处理类型，如果为2（兑换码），需要给兑换码添加随机的8位兑换码
        // 兑换码：大小写英文与数字   避免碰撞
        if (marketCoupon.getType() == 2) {
            String cdk = CdkCreateUtils.getCDK();
            marketCoupon.setCode(cdk);
        }else if (marketCoupon.getType() == 1){
            marketCoupon.setLimit(couponLimit);
        }
        // 添加开始时间和结束时间 day
        Short days = marketCoupon.getDays();
        if (days != 0) {
            // 同时设置开始时间和结束时间
            marketCoupon.setStartTime(new Date());
            Date dateAfter = getDateAfter(new Date(), days);
            marketCoupon.setEndTime(dateAfter);
        }else{
            // 如果day 为null,那么开始和结束时间不为null
            long time = marketCoupon.getEndTime().getTime() - marketCoupon.getStartTime().getTime();
            // 计算差多少天
            long diff = time/(1000*24*60*60);
            String s = Long.toString(diff);
            short day = Short.parseShort(s);
            marketCoupon.setDays(day);
        }

        couponMapper.insertSelective(marketCoupon);

        Integer id = marketCoupon.getId();

        return couponMapper.selectByPrimaryKey(id);
    }

    @Transactional
    @Override
    public MarketCoupon updateCouponInfo(MarketCoupon coupon) {
        // 修改时间
        coupon.setUpdateTime(new Date());

        couponMapper.updateByPrimaryKeySelective(coupon);

        return couponMapper.selectByPrimaryKey(coupon.getId());
    }

    @Transactional
    @Override
    public int deleteCoupon(MarketCoupon coupon) {
        Integer id = coupon.getId();
        // 直接修改delete字段  逻辑删除
        coupon.setDeleted(true);
        int i = couponMapper.updateByPrimaryKeySelective(coupon);
        // 实际删除
        // int i = couponMapper.deleteByPrimaryKey(id);
        if (i > 0) {
            return BaseRespVo.STATUS_OK;
        }
        return BaseRespVo.STATUS_DELETE_FAILED;

    }

    @Override
    public CommonData queryUserFromCoupon(BasePageInfo info, Integer couponId, Integer userId, Integer status) {
        // 开启分页
        PageHelper.startPage(info.getPage(), info.getLimit());

        // 查询 用户优惠券id,用户id,领取时间，使用状态，订单id,使用时间
        List<MarketCouponUser> list = couponUserMapper.selectByCouponId(couponId, userId, status);

        PageInfo<MarketCouponUser> marketCouponUserPageInfo = new PageInfo<>(list);

        return CommonData.data(marketCouponUserPageInfo);
    }

    @Override
    public CommonData<WxUserCouponVo> queryCouponByUserId(BasePageInfo pageInfo, Integer uid, Integer status) {
        PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit());

        List<WxUserCouponVo> list = couponMapper.queryAllCouponByUserId(uid, status);

        PageInfo<WxUserCouponVo> wxUserCouponVoPageInfo = new PageInfo<>(list);

        return CommonData.data(wxUserCouponVoPageInfo);
    }

    @Override
    public boolean queryHaveQuota(Integer userId, Integer couponId) {
        // 1.查询优惠券-用户表，获取用户已有优惠券的数量
        Short hasNum = couponMapper.selectNumHaved(userId, couponId);
        // 2.查询优惠券的限额
        MarketCoupon marketCoupon = couponMapper.selectByPrimaryKey(couponId);
        Short limit = marketCoupon.getLimit();
        // 3.进行校验
        if ((limit - hasNum) > 0) {
            return true;
        }
        return false;
    }

    @SneakyThrows
    @Transactional
    @Override
    public boolean receiveCouponForUser(Integer userId, Integer couponId) {

        MarketCoupon marketCoupon = couponMapper.selectByPrimaryKey(couponId);
        // 如果优惠券无限制，则不用扣减，否则需要扣减优惠券数量
        Integer total = marketCoupon.getTotal();
        if (total != 0) {
            total = total - 1;
        }
        couponMapper.updateByPrimaryKeySelective(marketCoupon);

        // 用户增加优惠券
        MarketCouponUser marketCouponUser = new MarketCouponUser();
        marketCouponUser.setAddTime(new Date());
        marketCouponUser.setUpdateTime(new Date());
        marketCouponUser.setCouponId(couponId);
        marketCouponUser.setUserId(userId);
        marketCouponUser.setStartTime(marketCoupon.getStartTime());
        marketCouponUser.setEndTime(marketCoupon.getEndTime());

        if (couponUserMapper.insertSelective(marketCouponUser) > 0) {
            return true;
        }
        return false;

    }


    @Override
    public CommonData<WxUserCouponVo> queryAll(Integer userId, BigDecimal checkedPrice) {

        // 查询用户所有的优惠券
        List<MarketCouponUser> couponUserList = queryList(userId, null, CouponUserConstant.STATUS_USABLE, null, null, "add_time", "desc");

        if (couponUserList == null) {
            return null;
        }

        List<WxUserCouponVo> couponVoList = change(couponUserList);

        PageHelper.startPage(1, couponVoList.size());

        for (WxUserCouponVo couponVo : couponVoList) {
            // 根据价格检查可用的优惠券
            // if (couponService.checkCoupon(couponVo,checkedPrice)){
            //     // resultCoupons.add(couponVo);
            // }
            checkCoupon(couponVo, checkedPrice);
        }

        PageInfo<WxUserCouponVo> page = new PageInfo<>(couponVoList);

        return CommonData.data(page);
    }

    /*
     * @Description 检查优惠券是否可用
     * @param
     * @return
     * @date 2022-11-22 19:27
     * @auther yxy_8175@163.com
     */
    @Override
    public void checkCoupon(WxUserCouponVo couponVo, BigDecimal checkedPrice) {
        MarketCoupon marketCoupon = couponMapper.selectByPrimaryKey(couponVo.getCid());
        BigDecimal min = marketCoupon.getMin();
        if ((checkedPrice.compareTo(min)) >= 0) {
            couponVo.setAvailable(true);
        } else {
            couponVo.setAvailable(false);
        }

    }

    @Transactional
    @Override
    public Short exchangeCouponByCDK(Integer userId, String code) {
        // 1.查询所有的兑换码
        MarketCouponExample example = new MarketCouponExample();
        MarketCouponExample.Criteria criteria = example.createCriteria();
        if (code != null) {
            criteria.andCodeEqualTo(code);
        }
        criteria.andDeletedEqualTo(false);
        List<MarketCoupon> list = couponMapper.selectByExample(example);
        // 判断兑换码是否存在且唯一
        if (list.size() != 1) {
            return CouponUserConstant.CDK_HAS_FAILED;
        }
        // 判断是否失效
        MarketCoupon marketCoupon = list.get(0);
        Date nowTime = new Date();
        Date startTime = marketCoupon.getStartTime();
        Date endTime = marketCoupon.getEndTime();
        if (startTime != null && endTime != null) {
            // 不为空的情况下，判断是否在活动时间内
            if ((nowTime.compareTo(startTime) < 0) || (nowTime.compareTo(endTime) > 0)) {
                return CouponUserConstant.CDK_OUT_OF_USE_TIME;
            }
        }

        Integer couponId = marketCoupon.getId();
        if (!receiveCouponForUser(userId, couponId)) {
            return CouponUserConstant.CDK_ALREADY_HAVE;
        }
        return CouponUserConstant.STATUS_OK;
    }

    /*
     * @Description TODO 给新人用户发放优惠券
     * @param userId
     * @return
     * @date 2022-11-25 0:35
     * @auther yxy_8175@163.com
    */
    @Override
    public void ProvideCoupon(Integer userId) {
        // 遍历所有优惠券，查询所有type 为 1（注册赠券）
        Short couponType = 1;
        MarketCouponExample example = new MarketCouponExample();
        example.or()
                .andTypeEqualTo(couponType)
                .andDeletedEqualTo(false);
        List<MarketCoupon> list = couponMapper.selectByExample(example);

        // 遍历所有符合的优惠券给用户
        for (MarketCoupon marketCoupon : list) {
            receiveCouponForUser(userId,marketCoupon.getId());
        }
    }


    /*
     * @Description  转换类型，将List<MarketCouponUser>  ====> List<WxUserCouponVo>
     * @param
     * @return
     * @date 2022-11-22 16:59
     * @auther yxy_8175@163.com
     */
    private List<WxUserCouponVo> change(List<MarketCouponUser> couponUserList) {
        ArrayList<WxUserCouponVo> couponVoList = new ArrayList<>(couponUserList.size());

        for (MarketCouponUser marketCouponUser : couponUserList) {
            Integer couponId = marketCouponUser.getCouponId();
            MarketCoupon coupon = couponMapper.selectByPrimaryKey(couponId);
            WxUserCouponVo couponVo = new WxUserCouponVo();
            couponVo.setId(marketCouponUser.getId());
            couponVo.setCid(coupon.getId());
            couponVo.setName(coupon.getName());
            couponVo.setDesc(coupon.getDesc());
            couponVo.setTag(coupon.getTag());
            couponVo.setMin(coupon.getMin());
            couponVo.setDiscount(coupon.getDiscount());
            couponVo.setStartTime(marketCouponUser.getStartTime());
            couponVo.setEndTime(marketCouponUser.getEndTime());
            // 将获取的优惠券信息 添加至结果容器中
            couponVoList.add(couponVo);
        }
        return couponVoList;
    }

    /*
     * @Description 根据条件来查询表
     * @param
     * @return
     * @date 2022-11-22 16:32
     * @auther yxy_8175@163.com
     */
    private List<MarketCouponUser> queryList(Integer userId, Integer couponId, Short status, Integer page, Integer size, String sort, String order) {
        MarketCouponUserExample example = new MarketCouponUserExample();
        MarketCouponUserExample.Criteria criteria = example.createCriteria();
        // 用户Id
        if (userId != null) {
            criteria.andUserIdEqualTo(userId);
        }
        // 优惠券Id
        if (couponId != null) {
            criteria.andCouponIdEqualTo(couponId);
        }
        // 是否可用
        if (status != null) {
            criteria.andStatusEqualTo(status);
        }
        criteria.andDeletedEqualTo(false);

        if (!StringUtil.isEmpty(sort) && !StringUtil.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        if (page != null && size != null) {
            PageHelper.startPage(page, size);
        }
        return couponUserMapper.selectByExample(example);

    }

    /*
     * @Description 获取days天后的日期
     * @param
     * @return
     * @date 2022-11-22 20:05
     * @auther yxy_8175@163.com
     */
    private Date getDateAfter(Date nowTime, int days) {
        Calendar now = Calendar.getInstance();
        now.setTime(nowTime);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + days);
        return now.getTime();
    }

}
